import sys, os, shutil, time
import glob
from pathlib import Path
from distutils.core import setup
from Cython.Build import cythonize


class EncryptProject:
    def __init__(self, project_dir, exclude=[]):
        self.pys = []
        self.cs = []
        self.exs = []
        self.cpps = []
        code_root = os.path.abspath(project_dir)
        f = Path(code_root)
        self.project_name = f.name
        self.project_dir = project_dir

        self.base = os.path.join(code_root, self.project_name)
        if os.path.exists(self.base):
            shutil.rmtree(self.base)
        self.build_dir = os.path.join(self.base, 'src')
        self.code_root = os.path.join(code_root, 'src')

        search_root = os.path.join(self.code_root, '**', '*.py')
        for path in glob.glob(search_root, recursive=True):
            f = Path(path)
            fc = False
            for exf in exclude:
                if exf in f.parts:
                    fc = True
                    break
            if fc:
                continue

            if path.endswith('.py'):
                name = os.path.basename(path)
                if name.startswith('__'):
                    so_path = path.replace(code_root, self.base)
                    self.exs.append((path, so_path))

                else:
                    self.pys.append(path)
                    cfile = path.replace('.py', '.c')
                    self.cs.append(cfile)
                    cppfile = path.replace('.py', '.cpp')
                    self.cpps.append(cppfile)

    def setup(self):
        start = time.time()
        build_temp = os.path.join(self.build_dir, 'temp')
        setup(ext_modules=cythonize(self.pys), script_args=["build_ext", "-b", self.build_dir, "-t", build_temp])

        for cfile in self.cs:
            if os.path.exists(cfile):
                os.remove(cfile)

        for cppfile in self.cpps:
            if os.path.exists(cppfile):
                os.remove(cppfile)

        if os.path.exists(build_temp):
            shutil.rmtree(build_temp)

        for init_src, init_dst in self.exs:
            shutil.copy(init_src, init_dst)

        shutil.copy(os.path.join(self.project_dir, 'setup.py'), self.base)
        shutil.copy(os.path.join(self.project_dir, 'MANIFEST.in'), self.base)

        data_path = os.path.join(self.project_dir, 'src', self.project_name, 'data')
        if os.path.exists(data_path):
            data_dest = os.path.join(self.build_dir, self.project_name)
            shutil.copy(data_path, data_dest)

        print('compile time: %.2fs' % (time.time() - start))

        cmd = 'cd %s; python3 setup.py sdist'% (self.base)
        os.system(cmd)

        sdist = os.path.join(self.base, 'dist')
        odist = os.path.join(self.project_dir, 'dist')
        if not os.path.exists(odist):
            os.makedirs(odist)

        for name in os.listdir(sdist):
            if not name.endswith('.tar.gz'):
                continue

            src = os.path.join(sdist, name)
            dst = os.path.join(odist, name.replace('.tar.gz', '-%s.tar.gz' % sys.platform))
            if os.path.isfile(dst):
                os.remove(dst)
            shutil.move(src, dst)
            break

        if os.path.exists(self.base):
            shutil.rmtree(self.base)
